package com.situ.mall.filter;

import com.situ.mall.util.JwtUtil;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Map;

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");

        String role = exchange.getRequest().getHeaders().getFirst("role");
        //如果是前台用户的请求
        if ("user".equals(role)) {
            // /product/category/selectTopCategoryList
            String path = exchange.getRequest().getURI().getPath();
            if (!path.startsWith("/order") //购物车、订单
                    && !path.startsWith("/user")) { //用户个人信息
                return chain.filter(exchange);
            }
        }

        // 白名单路径（比如 /login、/register 不需要校验）
        String path = exchange.getRequest().getURI().getPath();
        if (path.startsWith("/service/captcha")
                || path.startsWith("/admin/login")
                || path.startsWith("/admin/logout")
                || path.startsWith("/user/login")
                || path.startsWith("/user/register")
                || path.startsWith("/user/logout")) {
            return chain.filter(exchange);
        }

        try {
            //令牌是伪造的或者已经过期都会抛出异常
            Map<String, Object> map = JwtUtil.parseToken(token);
            //放行
            return chain.filter(exchange);
        } catch (Exception e) {
            //http的响应状态改成401
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
    }

    @Override
    public int getOrder() {
        return -1; // 优先级，数值越小越先执行
    }
}
